package nettyTest.client;


import com.zyc.remoting.dto.RpcRequest;
import com.zyc.remoting.dto.RpcResponse;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import nettyTest.coder.NettyKryoDecoderDemo;
import nettyTest.coder.NettyKryoEncoderDemo;
import nettyTest.serialize.KryoSerializerDemo;

/**
 * @author zyc
 * @create 2022--05--31 15:53
 */
public class NettyClientDemo {
    private final String host;
    private final int port;
    private static final Bootstrap BOOTSTRAP;

    public NettyClientDemo(String host, int port) {
        this.host = host;
        this.port = port;
    }

    static {
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        BOOTSTRAP = new Bootstrap();
        KryoSerializerDemo kryoSerializer = new KryoSerializerDemo();
        BOOTSTRAP.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                // 连接的超时时间，每15秒发送一次心跳请求
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //添加自定义编解码器
                        //对于客户端需要把请求编码，对响应解码
                        ch.pipeline().addLast(new NettyKryoDecoderDemo(kryoSerializer, RpcResponse.class));
                        ch.pipeline().addLast(new NettyKryoEncoderDemo(kryoSerializer, RpcRequest.class));

                        ch.pipeline().addLast(new NettyClientHandlerDemo());

                    }
                });

    }

    public RpcResponse sendMessage(RpcRequest rpcRequest) {
        try {
            ChannelFuture f = BOOTSTRAP.connect(host, port).sync();
            System.out.println("客户端连接" + host + ":" +port);
            Channel futureChannel = f.channel();
            System.out.println("开始发送信息");
            if (futureChannel != null) {
                futureChannel.writeAndFlush(rpcRequest).addListener(new GenericFutureListener<Future<? super Void>>() {
                    @Override
                    public void operationComplete(Future<? super Void> future) throws Exception {
                        if (future.isSuccess()) {
                            System.out.println("发送成功");
                        } else {
                            System.out.println("发送失败");
                        }
                    }
                });
                futureChannel.closeFuture().sync();
                AttributeKey<RpcResponse> key = AttributeKey.valueOf("rpcResponse");
                return futureChannel.attr(key).get();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

}
